
************************************************************************************************************************
*											 Reproduction code for: 												   *
******************************************* Blocking the Radical Right: ************************************************
************** Evidence from Strategic Candidate Voting Against the AfD in Germany's 2025 Federal Election *************
**************************************** Sven Hillen & Jessica Kuhlmann ************************************************
**************************************** Politische Vierteljahresschrift ***********************************************
************************************************************************************************************************

/*
Instructions:
This do-file reproduces all findings reported in the article listed above.
To reproduce the findings, do the following
1. Download datasets
	a) GLES (2025) post-election data: https://search.gesis.org/research_data/ZA10100
	b) Data with district-level indicators from our reproduction archive
3. Put the two datasets and this reproduction do-file into one folder (and set this as the working directory)
4. Run the code below on the combined dataset
*/


*** set working directory


**# Bookmark #1
************************************************************************************************************************
*************************************************** General Settings ***************************************************
************************************************************************************************************************

graph set window fontface "Times New Roman"

	
**# Bookmark #2
************************************************************************************************************************
*************************************************** Open and Recode GLES data ******************************************
************************************************************************************************************************
clear


***** Merge GLES with district-level data
use "ZA10100_v1-0-0.dta", clear

rename wknr Wahlkreisnr
merge m:1 Wahlkreisnr using "final_dataset.dta"

decode q114ab, gen(q114ab_string)
decode q114bb, gen(q114bb_string)
decode q122b, gen(q122b_string)


****** Polarization and Left/Right-Attitudes
gen lrscale = q37 
replace lrscale = . if lrscale < 0

gen challenger_value = .
replace challenger_value = q35b if gegenkandidat_partei == "CDU"
replace challenger_value = q35c if gegenkandidat_partei == "CSU"
replace challenger_value = q35d if gegenkandidat_partei == "SPD"
replace challenger_value = q35f if gegenkandidat_partei == "GRÜNE"
replace challenger_value = q35g if gegenkandidat_partei == "Die Linke"
replace challenger_value = . if challenger_value < 0

gen AfD_value = q35h
replace AfD_value = . if AfD_value < 0

gen distance_AfD_challenger = abs(AfD_value - challenger_value)
gen distance_AfD_respondent = abs(AfD_value - lrscale)


****** Combining CDU/CSU voters and exclusion of the AfD 
replace q122b_string = "CDU/CSU" if inlist(q122b_string, "CDU", "CSU")
replace q114ab_string = "CDU/CSU" if inlist(q114ab_string, "CDU", "CSU")
replace q114bb_string = "CDU/CSU" if inlist(q114bb_string, "CDU", "CSU")
drop if (q114ab_string == "AfD" | q114bb_string == "AfD" | q122b_string == "AfD")


***********************
* Dependent variables *
***********************
****** Difference between candidate and district vote (Spli-ticket voting)
gen TicketSplitting = .
replace TicketSplitting = q114ab_string != q114bb_string if !missing(q114ab_string, q114bb_string)


****** Vote for strongest challenger instead of party identification 
replace gegenkandidat_partei = "CDU/CSU" if inlist(gegenkandidat_partei, "CDU", "CSU")
tab gegenkandidat_partei
gen vote_challenger = .
replace vote_challenger = 1 if q114ab_string == gegenkandidat_partei & q122b_string != gegenkandidat_partei 
replace vote_challenger = 0 if q114ab_string != gegenkandidat_partei & !missing(q114ab_string, q122b_string, gegenkandidat_partei)

gen ChallengerVoting = vote_challenger // voters with challenger party as preference as missing
replace ChallengerVoting = . if q114ab_string == gegenkandidat_partei & q122b_string == gegenkandidat_partei


****** Only respondents who voted in the election
gen vote = .
replace vote = 1 if q111 == 1
replace vote = 0 if q111 == 2
keep if vote == 1 & !missing(vote)


*********************
* Sociodemographics *
*********************
****** Age
replace d2a = "" if d2a == "-99 keine Angabe"
replace d2a = "1935" if d2a == "1935 oder frueher" 
destring d2a, replace
gen age = 2025-d2a


****** Gender
gen female = .
replace female = 0 if d1 == 1
replace female = 1 if d1 == 2
label define female 0 "male" 1 "female"
label values female female


****** Education: Classification according to  ISCED 2011 (Source: https://search.gesis.org/variables/exploredata-ZA5240_VarV102)
fre d7 // School leaving certificate
fre d8g d8o d8p d8h d8q d8b d8c d8d d8k d8a d8e d8l d8f d8i d8e // Higher education

replace d7 = . if d7 < 0 
gen education = .
replace education = . if d7 == 9
replace education = 1 if d7 == 1 // Primary education (without school leaving certificate)
replace education = 2 if inlist(d7, 2, 3) & ///
    missing(d8b, d8c, d8d, d8f) // Lower secondary education 
replace education = 3 if inlist(d7, 2, 3) & ///
    (!missing(d8b) | !missing(d8c) | !missing(d8d) | !missing(d8f))
replace education = 3 if inlist(d7, 4, 5) & ///
    missing(d8c, d8d) // Upper secondary education 
replace education = 4 if inlist(d7, 4, 5) & ///
    (!missing(d8c) | !missing(d8d)) // Post-secondary non-tertiary education 
replace education = 5 if d8g == 1 | d8h == 1 // Short-cycle tertiary education 
replace education = 6 if d8i == 1 | d8o == 1 // Bachelor's or equivalent
replace education = 7 if d8p == 1 // Master's or equivalent
replace education = 8 if d8q == 1 // Doctoral or equivalent

label define education ///
    1 "Primary education" ///
    2 "Lower secondary education" ///
    3 "Upper secondary education" ///
    4 "Post-secondary non-tertiary" ///
    5 "Short-cycle tertiary" ///
    6 "Bachelor or equivalent" ///
    7 "Master or equivalent" ///
    8 "Doctorate or equivalent"

label values education education
fre education  


************************************
* Attitudes and electoral behavior *
************************************
gen decision_time = q115 
replace decision_time = . if inlist(decision_time, -99, -98, -97)

gen pol_interest = q1 
replace pol_interest = . if inlist(pol_interest, -99, -73)
replace pol_interest = 6 - pol_interest

gen party_attachment = q123
replace party_attachment = . if inlist(party_attachment, -99, -97, -73)
replace party_attachment = 4 - party_attachment 


**# Bookmark #3
************************************************************************************************************************
***************************************************** Multi-level models ***********************************************
************************************************************************************************************************

********************************
* Table 2: Split-ticket voting *
********************************
melogit TicketSplitting || Wahlkreisnr: 
estat icc	


****** M1: Individual-level indicators
melogit TicketSplitting c.AfD_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_M1
	margins, dydx(*) post  
	eststo ame_Split_M1 
	
	
****** M2: Individual- and district-level indicators
melogit TicketSplitting c.AfD_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_M2
	tab TicketSplitting if e(sample)
	margins, dydx(*) post  
	eststo ame_Split_M2
	
	
****** M3: Interaction with AfD competitive gap
melogit TicketSplitting c.AfD_Erststimmen_100##c.afd_competitive_gap c.pol_interest i.female c.age c.education c.lrscale /// 
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.Diff_valid_votes c.ratio_SMD_PR c.margin_top2  ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_M3


	// Figure 4: Predicted probabilities of split-ticket voting by competitive gap 
	margins, at(afd_competitive_gap=(0(0.5)35)) predict(pr)
	marginsplot,  title("", margin(b=5)) ///
		ytitle("") xtitle("Competitive gap AfD") ///
		addplot(hist afd_competitive_gap if e(sample), percent yaxis(2) ///
		yscale(alt range(0 50) axis(2)) yscale(lstyle(none) axis(2)) ///
		ytitle("", size(zero) axis(2)) ylabel(none, axis(2)) ///
		xlabel(0(5)35, gmin gmax) color(%40)) ///
		recast(line) recastci(rarea) ///
		yline(0) legend(off) ///
		name(test, replace)
	
	estimates restore m_Split_M3
	margins, dydx(*) post
	eststo ame_Split_M3
	
	// AMEs for interaction competitive gap
	gen interaction_competitivegap = AfD_Erststimmen_100 * afd_competitive_gap
	melogit TicketSplitting c.AfD_Erststimmen_100 c.afd_competitive_gap c.pol_interest i.female c.age c.education c.lrscale /// 
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.Diff_valid_votes c.ratio_SMD_PR c.margin_top2  ///
		c.interaction_competitivegap || Wahlkreisnr:, vce(cluster Bundesland)
	margins, dydx(*) post

		
****** M4: Interaction with political interest
	melogit TicketSplitting c.AfD_Erststimmen_100##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_M4

	// Figure 5: Effects of the AfD candidate vote on split-ticket voting by political interest
	margins, dydx(AfD_Erststimmen_100) at(pol_interest = (1(1)5))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Political interest") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist pol_interest if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
		xlabel(1 "No interest" 2 " " 3 " " 4 " " 5 "High interest", gmin gmax) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)

	estimates restore m_Split_M4
	margins, dydx(*) post
	eststo ame_Split_M4
	
	// AMEs for interaction
	gen interaction_interest = AfD_Erststimmen_100 * pol_interest
	melogit TicketSplitting c.AfD_Erststimmen_100 c.afd_competitive_gap c.pol_interest i.female c.age c.education c.lrscale /// 
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.Diff_valid_votes c.ratio_SMD_PR c.margin_top2  ///
		c.interaction_interest || Wahlkreisnr:, vce(cluster Bundesland)
	margins, dydx(*) post

	
esttab m_Split_M1 m_Split_M2 m_Split_M3 m_Split_M4 using "TicketSplitting_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace

esttab ame_Split_M1 ame_Split_M2 ame_Split_M3 ame_Split_M4 using "TicketSplitting_ame.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


******************************
* Table 3: Challenger Voting * 
******************************
melogit ChallengerVoting || Wahlkreisnr: 
estat icc


****** M1: Individual-level indicators
melogit ChallengerVoting c.AfD_Erststimmen_100 c.pol_interest i.female c.age c.education  /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_M1
	estat ic
	margins, dydx(*) post  
	eststo ame_Challenger_M1
	
	
****** M2: Individual- and district-level indicators
melogit ChallengerVoting c.AfD_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_M2
	tab ChallengerVoting if e(sample)
	margins, dydx(*) post 
	eststo ame_Challenger_M2
	
	
****** M3: Interaction with AfD competitive gap
	melogit ChallengerVoting c.AfD_Erststimmen_100##c.afd_competitive_gap c.pol_interest i.female c.age c.education /// 
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		c.ratio_SMD_PR || Wahlkreisnr:, vce(cluster Bundesland)
		eststo m_Challenger_M3
			
		// Figure 6. Predicted probabilities of challenger voting by competitive gap 
		margins, at(afd_competitive_gap=(0(0.5)35)) predict(pr) 
		
		marginsplot,  title("", margin(b=5)) ///
			ytitle("") xtitle("Competitive gap AfD") ///
			addplot(hist afd_competitive_gap if e(sample), percent yaxis(2) ///
			yscale(alt range(0 50) axis(2)) yscale(lstyle(none) axis(2)) ///
			ytitle("", size(zero) axis(2)) ylabel(none, axis(2)) ///
			xlabel(0(5)35, gmin gmax) color(%40)) ///
			recast(line) recastci(rarea) ///
			yline(0) legend(off) ///
			name(test, replace)	
		
	estimates restore m_Challenger_M3
	margins, dydx(*) post
	eststo ame_Challenger_M3
	
	// AMEs for interaction
	melogit ChallengerVoting c.AfD_Erststimmen_100 c.afd_competitive_gap c.pol_interest i.female c.age c.education /// 
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.Diff_valid_votes c.ratio_SMD_PR c.margin_top2  ///
		interaction_competitivegap || Wahlkreisnr:, vce(cluster Bundesland)
	margins, dydx(*) post
	
	
****** M4: Interaction with political interest
	melogit ChallengerVoting c.AfD_Erststimmen_100##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_M4
	
	// Figure 7. Effects of the AfD candidate vote on challenger voting by political interest 
	margins, dydx(AfD_Erststimmen_100) at(pol_interest = (1(1)5))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Political interest") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist pol_interest if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
		xlabel(1 "No interest" 2 " " 3 " " 4 " " 5 "High interest", gmin gmax) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)

	estimates restore m_Challenger_M4
	margins, dydx(*) post
	eststo ame_Challenger_M4
	
	// AMEs for interaction
	melogit ChallengerVoting c.AfD_Erststimmen_100 c.afd_competitive_gap c.pol_interest i.female c.age c.education /// 
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.Diff_valid_votes c.ratio_SMD_PR c.margin_top2  ///
		interaction_interest || Wahlkreisnr:, vce(cluster Bundesland)
	margins, dydx(*) post
	

esttab m_Challenger_M1 m_Challenger_M2 m_Challenger_M3 m_Challenger_M4 using "Challenger_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace

esttab ame_Challenger_M1 ame_Challenger_M2 ame_Challenger_M3 ame_Challenger_M4 using "Challenger_ame.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace



**# Bookmark #4
************************************************************************************************************************
***************************************** Appendix: Additional models **************************************************
************************************************************************************************************************


***** Table A5: Multilevel regression results on split-ticket voting with non-AfD candidate vote (Logits). 
gen CDU_CSU_Erststimmen_100 = CDU_Erststimmen_100
replace CDU_CSU_Erststimmen_100 = CSU_Erststimmen_100 if missing(CDU_CSU_Erststimmen_100)

melogit TicketSplitting c.CDU_CSU_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)  
		eststo m_Split_CDUCSU
		
melogit TicketSplitting c.SPD_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
		eststo m_Split_SPD
		
melogit TicketSplitting c.Grüne_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)  
		eststo m_Split_Greens
		
melogit TicketSplitting c.FDP_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
		eststo m_Split_FDP
		
melogit TicketSplitting c.Linke_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment  /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)		
		eststo m_Split_Left
		
esttab m_Split_CDUCSU m_Split_SPD m_Split_Greens m_Split_FDP m_Split_Left using "TicketSplitting_otherParties_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


***** Table A6: Multilevel regression results on challenger voting with non-AfD candidate vote (Logits). 
melogit ChallengerVoting c.CDU_CSU_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)  
		eststo m_Challenger_CDUCSU
		
melogit ChallengerVoting c.SPD_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
		eststo m_Challenger_SPD
		
melogit ChallengerVoting c.Grüne_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)  
		eststo m_Challenger_Greens
		
melogit ChallengerVoting c.FDP_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
		eststo m_Challenger_FDP
		
melogit ChallengerVoting c.Linke_Erststimmen_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)		
		eststo m_Challenger_Left
		
		
esttab m_Challenger_CDUCSU m_Challenger_SPD m_Challenger_Greens m_Challenger_FDP m_Challenger_Left using "Challenger_otherParties_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


***** Table A7: Multilevel regression results (Logits) – ideological distance. 
// M1: Interaction with ideological distance between AfD and challenger
	melogit TicketSplitting c.AfD_Erststimmen_100##c.distance_AfD_challenger i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.pol_interest c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_add_M1
	
	// Figure A3. Effects of the AfD candidate vote on split-ticket voting by distance between challenger and AfD  
	margins, dydx(AfD_Erststimmen_100) at(distance_AfD_challenger=(0(1)10))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Distance between Challenger and the AfD") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist distance_AfD_challenger if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)

// M2: Interaction with ideological distance between AfD and respondent
	melogit TicketSplitting c.AfD_Erststimmen_100##c.distance_AfD_respondent i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.pol_interest c.distance_AfD_challenger  /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_add_M2
	
	// Figure A4. Effects of the AfD candidate vote on split-ticket voting by distance between respondent and AfD  
	margins, dydx(AfD_Erststimmen_100) at(distance_AfD_respondent=(0(1)10))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Distance between Respondent and the AfD") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist distance_AfD_respondent if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)
	
	
// M3: Interaction with ideological distance between AfD and challenger
	melogit ChallengerVoting c.AfD_Erststimmen_100##c.distance_AfD_challenger i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.pol_interest c.distance_AfD_respondent  /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_add_M3
	
	// Figure A5. Effects of the AfD candidate vote on challenger voting by distance between challenger and AfD   
	margins, dydx(AfD_Erststimmen_100) at(distance_AfD_challenger=(0(1)10))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Distance between Challenger and the AfD") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist pol_interest if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)

// M4: Interaction with ideological distance between AfD and respondent
	melogit ChallengerVoting c.AfD_Erststimmen_100##c.distance_AfD_respondent i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.pol_interest c.distance_AfD_challenger  /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_add_M4
	
	// Figure A6. Effects of the AfD candidate vote on challenger voting by distance between respondent and AfD  
	margins, dydx(AfD_Erststimmen_100) at(distance_AfD_respondent=(0(1)10))
	marginsplot, ///
		title("", size(medsmall)) ///
		ytitle("Marginal effect of AfD candidate vote share") ///
		xtitle("Distance between Respondent and the AfD") ///
		yline(0, lpattern(dash)) ///
		name(AfD2025, replace) ///
		addplot( ///
	hist pol_interest if e(sample), percent yaxis(2) discrete ///        
		yscale(alt axis(2) range(0 1)) /// 
        ytitle("", axis(2) size(zero)) ///
        ylabel(none, axis(2)) ///
        color(%40) ///
        barwidth(0.95)) ///
    legend(off)

	
esttab m_Split_add_M1 m_Split_add_M2 m_Challenger_add_M3 m_Challenger_add_M4 using "IdeologicalDistance_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


************************
* 2021 election models *
************************
* Table A8: Multilevel regression results for split-ticket voting (Logits) – 2021 election results
// M1: Individual-level indicators
melogit TicketSplitting c.AfD_Erststimmen2021_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_2021_M1
	
// M2: Individual- and district-level indicators
melogit TicketSplitting c.AfD_Erststimmen2021_100 c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_2021_M2
	
// M3: Interaction with AfD competitive gap
melogit TicketSplitting c.AfD_Erststimmen2021_100##c.afd_competitive_gap c.pol_interest i.female c.age c.education c.lrscale /// 
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2  ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_2021_M3
		
// M4: Interaction with political interest
melogit TicketSplitting c.AfD_Erststimmen2021_100##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_2021_M4
	
	
esttab m_Split_2021_M1 m_Split_2021_M2 m_Split_2021_M3 m_Split_2021_M4 using "TicketSplitting_2021_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


* Table A9: Multilevel regression results for challenger voting (Logits) – 2021 election results
// M1: Individual-level indicators
melogit ChallengerVoting c.AfD_Erststimmen2021_100 c.pol_interest i.female c.age c.education  /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_2021_M1
	
// M2: Individual- and district-level indicators
melogit ChallengerVoting c.AfD_Erststimmen2021_100 c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_2021_M2
	
// M3: Interaction with AfD competitive gap
melogit ChallengerVoting c.AfD_Erststimmen2021_100##c.afd_competitive_gap c.pol_interest i.female c.age c.education /// 
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		c.ratio_SMD_PR || Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_2021_M3
	
// M4: Interaction with political interest
melogit ChallengerVoting c.AfD_Erststimmen2021_100##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2 ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_2021_M4
	

esttab m_Challenger_2021_M1 m_Challenger_2021_M2 m_Challenger_2021_M3 m_Challenger_2021_M4 using "Challenger_2021_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


*****************
* YouGov models *
*****************
* Table A10: Multilevel regression results for split-ticket voting (Logits) – YouGov models
// M1: Individual-level indicators
melogit TicketSplitting c.AfDShare c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_YouGov_M1
	
// M2: Individual- and district-level indicators
melogit TicketSplitting c.AfDShare c.pol_interest i.female c.age c.education c.lrscale c.party_attachment /// 	
		c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent ///
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_YouGov_M2
	
// M3: Interaction with AfD competitive gap
melogit TicketSplitting c.AfDShare##c.afd_competitive_gapYG c.pol_interest i.female c.age c.education c.lrscale /// 
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG  ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_YouGov_M3
		
// M4: Interaction with political interest
melogit TicketSplitting c.AfDShare##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Split_YouGov_M4
	
	
esttab m_Split_YouGov_M1 m_Split_YouGov_M2 m_Split_YouGov_M3 m_Split_YouGov_M4 using "TicketSplitting_YouGov_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace


* Table A11: Multilevel regression results for challenger voting (Logits) – YouGov models
// M1: Individual-level indicators
melogit ChallengerVoting c.AfDShare c.pol_interest i.female c.age c.education  /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_YouGov_M1
	
// M2: Individual- and district-level indicators
melogit ChallengerVoting c.AfDShare c.pol_interest i.female c.age c.education c.lrscale /// 	
		c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_YouGov_M2
	
// M3: Interaction with AfD competitive gap
melogit ChallengerVoting c.AfDShare##c.afd_competitive_gapYG c.pol_interest i.female c.age c.education /// 
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG ///
		c.ratio_SMD_PR || Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_YouGov_M3
	
// M4: Interaction with political interest
melogit ChallengerVoting c.AfDShare##c.pol_interest i.female c.age c.education /// 	
		c.lrscale c.party_attachment c.decision_time c.distance_AfD_challenger c.distance_AfD_respondent /// 
		i.incumbent_rival i.afd_amtsinhaber c.ratio_SMD_PR c.Diff_valid_votes c.margin_top2_YG ///
		|| Wahlkreisnr:, vce(cluster Bundesland)
	eststo m_Challenger_YouGov_M4
	

esttab m_Challenger_YouGov_M1 m_Challenger_YouGov_M2 m_Challenger_YouGov_M3 m_Challenger_YouGov_M4 using "Challenger_YouGov_logits.rtf", b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace





